Skip to content

fix: add GitHub raw fallback & reduced timeout for Pastebin manifest - #549

Open
nandhanay wants to merge 1 commit into
ProdigyV21:mainfrom
nandhanay:fix/pastebin-raw-fallback
Open

fix: add GitHub raw fallback & reduced timeout for Pastebin manifest#549
nandhanay wants to merge 1 commit into
ProdigyV21:mainfrom
nandhanay:fix/pastebin-raw-fallback

Conversation

@nandhanay

Copy link
Copy Markdown

Summary

Fixes #537

Hardcoded Pastebin dependency (https://pastebin.com/raw/P4gfd98n) caused a ~14-second TCP connection timeout on startup for users in Turkey and regions where Pastebin is blocked.

Changes

  • Config: Added repository-hosted config/streaming_addon.txt.
  • MediaRepository: Updated STREAMING_COLLECTION_ADDON_URL to GitHub raw URL and retained PASTEBIN_STREAMING_ADDON_URL as secondary fallback.
  • StreamRepository: Updated resolveAddonInstallUrl to use a 3.5s fast timeout and automatic fallback chain between GitHub raw and Pastebin.
  • HomeViewModel: Updated auto-installed addon cleanup list to handle both manifest URLs.
  • Unit Tests: Added StreamAddonFallbackTest.

keithmancuso1-stack commented Aug 11, 2026

Copy link
Copy Markdown

Thanks for addressing this so quickly. I reviewed the PR against the current StreamRepository / HomeViewModel flow, and the overall direction looks good: GitHub Raw becomes the primary remote pointer, Pastebin is retained as a fallback, and the old ~14-second blocked connection is bounded by the new 3.5-second fast client.

One remaining startup-path concern

There is one detail in the cleanup path that may still cause an unnecessary Pastebin connection attempt for users in regions where Pastebin is blocked.

HomeViewModel currently passes both pointers to cleanup:

streamRepository.removeCustomAddonsByUrl(
    CollectionTemplateManifest.autoInstalledAddonUrls() +
        listOf(
            MediaRepository.STREAMING_COLLECTION_ADDON_URL,
            MediaRepository.PASTEBIN_STREAMING_ADDON_URL
        )
)

However, removeCustomAddonsByUrl() resolves every supplied URL before deduplicating them:

val normalizedUrls = urls
    .mapNotNull { url ->
        runCatching { resolveAddonInstallUrl(url) }
            .getOrNull()
            ?.takeIf { it.isNotBlank() }
    }
    .distinct()
    .toSet()

And resolveAddonInstallUrl() already contains the GitHub Raw <-> Pastebin fallback chain.

That means the normal startup flow can become:

  1. Resolve STREAMING_COLLECTION_ADDON_URL (GitHub Raw).
  2. GitHub Raw succeeds and returns the actual addon/manifest URL.
  3. Cleanup then processes the explicit PASTEBIN_STREAMING_ADDON_URL entry separately.
  4. In Turkey, that Pastebin request can wait for the 3.5-second timeout.
  5. The resolver then falls back to GitHub Raw and resolves the same manifest URL again.
  6. Only after both network resolutions does .distinct() remove the duplicate.

So the PR should reduce the original ~14-second stall substantially, but the explicit Pastebin cleanup entry may still leave an avoidable ~3.5-second delay on the normal successful GitHub path.

Suggested minimal change

Unless the explicit Pastebin pointer is required for a separate migration case, I think the cleanup path only needs the primary pointer:

streamRepository.removeCustomAddonsByUrl(
    CollectionTemplateManifest.autoInstalledAddonUrls() +
        listOf(MediaRepository.STREAMING_COLLECTION_ADDON_URL)
)

This keeps the behavior surgical:

  • Normal path: GitHub Raw -> resolved manifest
  • GitHub unavailable: GitHub Raw -> Pastebin fallback
  • No proactive Pastebin request when GitHub Raw is healthy

The fallback itself remains fully available inside resolveAddonInstallUrl().

Why this should still clean up the installed addon

addCustomAddon() first calls resolveAddonInstallUrl(url) and then stores the resulting normalizedUrl in Addon.url:

val normalizedUrl = resolveAddonInstallUrl(url)
...
val newAddon = Addon(
    ...
    url = normalizedUrl,
    ...
)

So when the remote pointer resolves successfully, the installed addon is identified by the resolved addon URL, not by the Pastebin/GitHub pointer that was used to obtain it. Resolving the primary pointer once during cleanup should therefore produce the URL needed for matching.

Test coverage suggestion

The new StreamAddonFallbackTest currently verifies that the primary and fallback constants are configured correctly. It would be useful to add behavioral coverage for the actual request order as well, for example:

GitHub primary succeeds -> Pastebin is NOT requested
GitHub primary fails    -> Pastebin IS requested as fallback
Pastebin input fails    -> GitHub Raw IS requested as fallback

The first case is especially important for this issue because it guarantees that a blocked Pastebin endpoint stays completely off the normal startup path.

I would keep the fix focused on this request-order behavior rather than add extra caching at this stage; the repository-hosted pointer already provides a clean source of truth, and caching a resolved manifest URL could introduce stale-URL behavior unless expiry/invalidation is defined.

Overall, the PR is a good solution to the original issue. This is just a small follow-up that may remove the remaining blocked-domain wait entirely while preserving the fallback design. Thanks again for the quick response and implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pastebin dependency causes ~14s timeout for users in Turkey

2 participants